#include "ctp_hynitron_ext.h"
#include "bsp_board.h"
#include "driver_ctp816s.h"
#include "simulate_i2c.h"
//#include "capacitive_hynitron_cst816s_update_0617.h"
#include "platform.h"

static uint32_t Read_Ctp_Addr;

static bool cst816s_enter_bootmode(void)
{
    uint8_t retrycnt = 10;
    while (retrycnt--)
    {
        //uint8_t buf[3];
        uint8_t cmd = 0;
		uint16_t reg=0;
		
       // buf[0] = 0xA0;  // adress is A001, data is AB
       // buf[1] = 0x01;
       // buf[2] = 0xAB;
		reg = 0xA001;
		cmd = 0xAB;
        //hctp_write(buf, 3);
        I2C_MasterWrite_16Reg((BOOT_SLAVE<<1),reg,&cmd,1);
        //I2C_MasterWrite(0x6A,reg,buf,3);
        //platform_delay_ms(4);
         DelayMs(2);

        //buf[0] = 0xA0;
        //buf[1] = 0x03;
		reg = 0xA003;
		cmd  = 0xFF;
        //hctp_read(buf, 2, &cmd, 1);
		//I2C_read(0x6A,reg,&cmd, 1);
		I2C_read_16Reg((BOOT_SLAVE<<1),reg,&cmd,1);
		 DelayMs(2);
#if 1	//20220512 steven.liu
        if (cmd == 0x55) // cst716,cst816s 
#else
		if (cmd == 0xC1)	//cst816d
#endif
        {
           UART2_SendMgs(&cmd,1);
            return true;
        }
        else
        {
            //platform_delay_ms(4); // 4ms
            UART2_SendMgs(&cmd,1);
             DelayMs(2);
            continue;
        }
    }
    return false;
}

/////////////////////////////////////////////

static uint32_t cst816s_read_checksum(uint16_t startAddr, uint16_t len)
{

    uint8_t buf[2]={0};
    //uint8_t buf[3];
    uint8_t cmd = 0;
    uint16_t reg=0,sum=0;
		
    if (cst816s_enter_bootmode() == false)
    {
        return false;
    }

    //buf[0] = 0xA0;
    //buf[1] = 0x03;
    //buf[2] = 0;
	reg = 0xA003;
	cmd  = 0;
   // hctp_write(buf, 3);
	I2C_MasterWrite_16Reg((BOOT_SLAVE<<1),reg,&cmd,1);
   // platform_delay_ms(500);
    DelayMs(500);

    //checksum.sum = 0;
   // buf[0] = 0xA0;
   // buf[1] = 0x08;
	reg = 0xA008;
	//cmd  = 0;
    //hctp_read(buf, 2, checksum.buf, 2);
	I2C_read_16Reg((BOOT_SLAVE<<1),reg,buf,2);
    //APP_PRINT_INFO1("checksum 1 = 0x%x", checksum.sum);
    sum = buf[0];
	sum = (sum<<8) + buf[1];
    return sum;
}

/////////////////////////////////////////////

static bool cst816s_update(uint16_t startAddr, uint16_t len)//, uint32_t *src)
{
    uint16_t sum_len = 0;
    uint8_t cmd[10];
    uint8_t buf[4];
    uint16_t reg=0,i=0;
	uint32_t readvalue;
		
    if (cst816s_enter_bootmode() == false)
    {
        return false;
    }

	Read_Ctp_Addr = FLASH_START_ADDRESS + 16;
    //(uint32_t *)(Read_Ctp_Addr + 16));

#define PER_LEN 512
    //uint8_t buffer[PER_LEN + 2] = {0};
    uint8_t buffer[PER_LEN + 0] = {0};
    do
    {
    	//WDG_Kick();
    	//WDG_APP_Process();
		
        //DBG_DIRECT("startAddr = %d,  src = %d, sum_len = %d", startAddr, src, sum_len);
        if (sum_len >= len)
        {
            return true;
        }

        // send address
       // buf[0] = 0xA0;
       // buf[1] = 0x14;
       // buf[2] = startAddr & 0xFF;
       // buf[3] = startAddr >> 8;

        //hctp_write(buf, 4);
		reg = 0xA014;
		buf[0] = startAddr & 0xFF;
        buf[1] = startAddr >> 8;
		I2C_MasterWrite_16Reg((BOOT_SLAVE<<1),reg,buf,2);

        buffer[0] = 0xA0;
        buffer[1] = 0x18;
       // memcpy(buffer + 2, src, PER_LEN);
      //  hctp_write(buffer, PER_LEN + 2);
        reg = 0xA018;
	   #ifdef WRITE_IMAGE_CPT816S_DATA_IN_FLASH 
	   for(i=0;i<(PER_LEN/4);i++)
        { 
          //readvalue = *(src+i);
		  readvalue = *(uint32_t *)(Read_Ctp_Addr + i*4);
		  buffer[i*4+3] = (readvalue>>24)&0xFF;
          buffer[i*4+2] = (readvalue>>16)&0xFF;
          buffer[i*4+1] = (readvalue>>8)&0xFF;
          buffer[i*4] = (readvalue>>0)&0xFF;
	   	}
	   #else
		memcpy(buffer, src, PER_LEN);
	   #endif
        I2C_MasterWrite_16Reg((BOOT_SLAVE<<1),reg,buffer,PER_LEN);

       // buf[0] = 0xA0;
       // buf[1] = 0x04;
       // buf[2] = 0xEE;
      //  hctp_write(buf, 3);
		
		reg = 0xA004;
        buf[0] = 0xEE;
		I2C_MasterWrite_16Reg((BOOT_SLAVE<<1),reg,buf,1);

        DelayMs(100);
        {
            uint8_t retrycnt = 50;
            while (retrycnt--)
            {
                cmd[0] = 0;
               // buf[0] = 0xA0;
               // buf[1] = 0x05;
               // hctp_read(buf, 2, cmd, 1);				
                reg = 0xA005;
				I2C_read_16Reg((BOOT_SLAVE<<1),reg,cmd,1);
				
#if 1	//20220512 steven.liu
                if (cmd[0] == 0x55) // cst816s
#else
				if (cmd[0] == 0xC1)	//cst816d
#endif
                {
                    // success
                    //DBG_DIRECT("cst816s_update success");	//20220512 steven.liu
                    break;
                }
                DelayMs(10);
            }
        }
        startAddr += PER_LEN;
        //src += PER_LEN;
        Read_Ctp_Addr += PER_LEN;
        sum_len += PER_LEN;
    }
    while (len);

    // exit program mode

   // buf[0] = 0xA0;
   // buf[1] = 0x03;
   // buf[2] = 0x00;
   // hctp_write(buf, 3);

    reg = 0xA003;
	buf[0] = 0x00;
    I2C_MasterWrite_16Reg((BOOT_SLAVE<<1),reg,buf,1);
	
    return true;
}
/////////////////////////////////////////////



bool ctp_hynitron_update(void)
{
 uint16_t length=0,startAddr,checksum;
 uint32_t readvalue,readvalue_check1,readvalue_check2;
	
   TP_RES_CLR();
   DelayMs(10);
   TP_RES_SET();
   DelayMs(8);

 if (cst816s_enter_bootmode() == true)
 	{
 	  #ifdef WRITE_IMAGE_CPT816S_DATA_IN_FLASH
	     Read_Ctp_Addr = FLASH_START_ADDRESS;
	     readvalue =  *(volatile uint32_t *)(Read_Ctp_Addr);   // 32bit address
		 length = (readvalue>>24) & 0xFF; 
		 length <<= 8;		 
		 length |= (readvalue>>16) & 0xFF;

		 startAddr =  (readvalue>>8) & 0xFF; 
		 startAddr <<= 8;
         startAddr |= (readvalue) & 0xFF; 

         readvalue = *(volatile uint32_t *)(Read_Ctp_Addr+4); 
         checksum = (readvalue>>8) & 0xFF; 
		 checksum <<= 8;
         checksum |= (readvalue) & 0xFF; 

		  
	   if ((length > 0x800) && (length < 0x5000))  //   length>2K & length<20 k
      //if (sizeof(app_bin_816s) > 10)
        {

            //APP_PRINT_INFO2("checksum 0 = 0x%x, length = %d", checksum, length);
          	if(cst816s_read_checksum(startAddr, length) != checksum)	//20220512 steven.liu
	        {
	            cst816s_read_checksum(startAddr, length);	//20220512 steven.liu
	            //cst816s_update(startAddr, length, (uint8_t *)(app_bin_816s + 6));
	            //readvalue_check1 = *(uint32_t *)(Read_Ctp_Addr);
				//readvalue_check2 = *(uint32_t *)(Read_Ctp_Addr+16);
				//readvalue_check1 = *(uint32_t *)(Read_Ctp_Addr+32);

				cst816s_update(startAddr, length);//, (uint32_t *)(Read_Ctp_Addr + 16));
	            cst816s_read_checksum(startAddr, length);
				//DBG_DIRECT("cst816s fw update complete");
	               TP_RES_CLR();
                   DelayMs(10);
                   TP_RES_SET();
                   DelayMs(30);
	            static uint8_t chip_id = 0x59;
	            driver_touch_ctp816s_get_chip_id(&chip_id);
            }
			else {
				//DBG_DIRECT("TP fw checksum equal");
                 TP_RES_CLR();
                 DelayMs(10);
                 TP_RES_SET();
                 DelayMs(30);
				static uint8_t chip_id = 0x59;
	            driver_touch_ctp816s_get_chip_id(&chip_id);
			}
        }

	  #else
        if (sizeof(app_bin_816s) > 10)
        {
            uint16_t startAddr = app_bin_816s[1];
            uint16_t length = app_bin_816s[3];
            uint16_t checksum = app_bin_816s[5];
            startAddr <<= 8;
            startAddr |= app_bin_816s[0];
            length <<= 8;
            length |= app_bin_816s[2];
            checksum <<= 8;
            checksum |= app_bin_816s[4];
            //APP_PRINT_INFO2("checksum 0 = 0x%x, length = %d", checksum, length);
          	if(cst816s_read_checksum(startAddr, length) != checksum)	//20220512 steven.liu
	        {
	            cst816s_read_checksum(startAddr, length);	//20220512 steven.liu
	            cst816s_update(startAddr, length, (uint8_t *)(app_bin_816s + 6));
	            cst816s_read_checksum(startAddr, length);
				//DBG_DIRECT("cst816s fw update complete");
	               TP_RES_CLR();
                   DelayMs(10);
                   TP_RES_SET();
                   DelayMs(30);
	            static uint8_t chip_id = 0x59;
	            driver_touch_ctp816s_get_chip_id(&chip_id);
            }
			else {
				//DBG_DIRECT("TP fw checksum equal");
                 TP_RES_CLR();
                 DelayMs(10);
                 TP_RES_SET();
                 DelayMs(30);
				static uint8_t chip_id = 0x59;
	            driver_touch_ctp816s_get_chip_id(&chip_id);
			}
        }

		#endif 
        return true;
 	} 
 
   return true;

}




///////////////////////////////////////

